package com.nlelpct.manage.service.impl;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nlelpct.manage.constant.SystemConstant;
import com.nlelpct.manage.context.ThreadParameter;
import com.nlelpct.manage.mapper.SysCompanyMenuMapper;
import com.nlelpct.manage.mapper.SysMenuMapper;
import com.nlelpct.manage.model.entity.SysCompanyMenu;
import com.nlelpct.manage.model.entity.SysMenu;
import com.nlelpct.manage.model.vo.CurrentMenuVo;
import com.nlelpct.manage.model.vo.MenuVo;
import com.nlelpct.manage.model.vo.MyCurrentMenuVo;
import com.nlelpct.manage.model.vo.ResponseResult;
import com.nlelpct.manage.service.ISysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author :小马
 * @date : 2023-10-12
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    private final SysMenuMapper sysMenuMapper;

    private final SysCompanyMenuMapper sysCompanyMenuMapper;

    @Autowired
    public SysMenuServiceImpl(SysMenuMapper sysMenuMapper, SysCompanyMenuMapper sysCompanyMenuMapper) {
        this.sysMenuMapper = sysMenuMapper;
        this.sysCompanyMenuMapper = sysCompanyMenuMapper;
    }

    @Override
    public ResponseResult<List<MenuVo>> getMenuStructure() {
        List<MenuVo> result = new ArrayList<>();
        // 菜单状态：（0停用 1正常）
        List<SysMenu> list = sysMenuMapper.getMenuByCompany(ThreadParameter.getLocalData(SystemConstant.SYSTEM_ID), ThreadParameter.getLocalData(SystemConstant.COMPANY_ID));
        // 根据是否是按钮进行分组
        Map<Boolean, List<SysMenu>> menuTypeMap = list.stream().collect(Collectors.partitioningBy(menu -> menu.getMenuType() == 3));
        List<SysMenu> sysCatalogues = menuTypeMap.get(Boolean.FALSE);
        List<SysMenu> sysButtons = menuTypeMap.get(Boolean.TRUE);
        if (!ObjectUtil.isEmpty(sysCatalogues)) {
            // 顶级目录
            List<SysMenu> topLevelDirectory = sysCatalogues.parallelStream().filter(menu -> ObjectUtil.isEmpty(menu.getParentId())).collect(Collectors.toList());
            String parentId;
            for (SysMenu sysMenu : topLevelDirectory) {
                parentId = sysMenu.getParentId();
                MenuVo menuVo = new MenuVo();
                menuVo.setMenuId(sysMenu.getMenuId());
                menuVo.setMenuName(sysMenu.getName());
                menuVo.setParentId(parentId);
                menuVo.setOrderNum(sysMenu.getOrderNum());
                menuVo.setMenuType(sysMenu.getMenuType());
                menuVo.setChildren(handlerMenu(sysMenu.getMenuId(), sysCatalogues, sysButtons));
                result.add(menuVo);
            }
        }
        if (!ObjectUtil.isEmpty(sysButtons)) {
            // 获取顶级按钮
            List<SysMenu> collect = sysButtons.parallelStream().filter(menu -> ObjectUtil.isEmpty(menu.getParentId())).collect(Collectors.toList());
            for (SysMenu sysMenu : collect) {
                MenuVo menuVo = new MenuVo();
                menuVo.setMenuId(sysMenu.getMenuId());
                menuVo.setMenuName(sysMenu.getName());
                menuVo.setParentId(sysMenu.getParentId());
                menuVo.setMenuType(sysMenu.getMenuType());
                menuVo.setOrderNum(sysMenu.getOrderNum());
                result.add(menuVo);
            }
        }

        return ResponseResult.success(result);
    }

    @Override
    public ResponseResult<MyCurrentMenuVo> getOwnedMenu() {
        MyCurrentMenuVo myCurrentMenuVo = new MyCurrentMenuVo();
        List<CurrentMenuVo> result = new ArrayList<>();
        List<String> menuIds = sysMenuMapper.getMenuIdByEmployeeId(ThreadParameter.getLocalData(SystemConstant.EMPLOYEE_ID));
        List<String> collect = sysCompanyMenuMapper.selectList(new LambdaQueryWrapper<SysCompanyMenu>().eq(SysCompanyMenu::getCompanyId, ThreadParameter.getLocalData(SystemConstant.COMPANY_ID))
                .select(SysCompanyMenu::getMenuId)).parallelStream().map(SysCompanyMenu::getMenuId).collect(Collectors.toList());
        menuIds = menuIds.parallelStream().filter(collect::contains).collect(Collectors.toList());
        if (ObjectUtil.isEmpty(menuIds)) {
            return ResponseResult.success(myCurrentMenuVo);
        }
        List<CurrentMenuVo> employeeMenuList = sysMenuMapper.getMenuByMenuIds(menuIds, ThreadParameter.getLocalData(SystemConstant.SYSTEM_ID));
        Map<Boolean, List<CurrentMenuVo>> menuTypeMap = employeeMenuList.stream().collect(Collectors.partitioningBy(menu -> menu.getMenuType() == 3));
        List<CurrentMenuVo> sysCatalogues = menuTypeMap.get(Boolean.FALSE);
        List<CurrentMenuVo> sysButtons = menuTypeMap.get(Boolean.TRUE);
        if (!ObjectUtil.isEmpty(sysCatalogues)) {
            // 顶级目录
            List<CurrentMenuVo> topLevelDirectory = sysCatalogues.parallelStream().filter(menu -> ObjectUtil.isEmpty(menu.getParentId())).collect(Collectors.toList());
            for (CurrentMenuVo sysMenu : topLevelDirectory) {
                sysMenu.setChildren(handlerCurrentEmployeeMenu(sysMenu.getMenuId(), sysCatalogues));
                result.add(sysMenu);
            }
        }
        myCurrentMenuVo.setCatalogueList(result);
        myCurrentMenuVo.setButtonList(sysButtons);
        return ResponseResult.success(myCurrentMenuVo);
    }

    /**
     * 获取给定目录Id的子目录和菜单
     *
     * @param menuId        目录ID
     * @param sysCatalogues 目录数据集合
     * @param sysButtons    菜单数据集合
     * @return 给定目录的孩儿们
     */
    private List<MenuVo> handlerMenu(String menuId, List<SysMenu> sysCatalogues, List<SysMenu> sysButtons) {
        // 先处理按钮 -- 按钮没有子按钮
        List<MenuVo> children = sysButtons.parallelStream().filter(menu -> menu.getParentId().equals(menuId))
                .map(menu -> {
                    MenuVo menuVo = new MenuVo();
                    menuVo.setMenuId(menu.getMenuId());
                    menuVo.setMenuName(menu.getName());
                    menuVo.setParentId(menu.getParentId());
                    menuVo.setMenuType(menu.getMenuType());
                    menuVo.setOrderNum(menu.getOrderNum());
                    return menuVo;
                }).collect(Collectors.toList());
        // 再处理子目录
        List<SysMenu> childrenCatalogue = sysCatalogues.parallelStream().filter(menu -> menu.getParentId().equals(menuId)).collect(Collectors.toList());
        for (SysMenu sysMenu : childrenCatalogue) {
            MenuVo menuVo = new MenuVo();
            menuVo.setMenuId(sysMenu.getMenuId());
            menuVo.setMenuName(sysMenu.getName());
            menuVo.setParentId(sysMenu.getParentId());
            menuVo.setMenuType(sysMenu.getMenuType());
            menuVo.setOrderNum(sysMenu.getOrderNum());
            menuVo.setChildren(handlerMenu(sysMenu.getMenuId(), sysCatalogues, sysButtons));
            children.add(menuVo);
        }
        return children;
    }

    private List<CurrentMenuVo> handlerCurrentEmployeeMenu(String menuId, List<CurrentMenuVo> sysCatalogues) {
        // 先处理按钮 -- 按钮没有子按钮
        List<CurrentMenuVo> children = new ArrayList<>();
        // 再处理子目录
        List<CurrentMenuVo> childrenCatalogue = sysCatalogues.parallelStream().filter(menu -> menu.getParentId().equals(menuId)).collect(Collectors.toList());
        for (CurrentMenuVo sysMenu : childrenCatalogue) {
            sysMenu.setChildren(handlerCurrentEmployeeMenu(sysMenu.getMenuId(), sysCatalogues));
            children.add(sysMenu);
        }
        return children;
    }
}
